package com.file.parser;

import com.file.bo.ResponseData;
import com.file.bo.mail.CMB;
import com.file.bo.mail.CMBTran;
import com.file.constant.ErrorCode;
import com.file.parser.traprange.PDFTableExtractor;
import com.file.util.JsonUtils;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import technology.tabula.*;
import technology.tabula.detectors.NurminenDetectionAlgorithm;
import technology.tabula.extractors.BasicExtractionAlgorithm;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class CMBPdfParser extends BasePdfParser {

    private static final Integer CMB_PDF_HEADER_LINE_NUMBER = 11;
    private static final Integer CMB_PDF_FOOTER_LINE_NUMBER = 5;

    public ResponseData<String> parseCMBPdfToJson(String daId, String filePath) {
        log.info("parseCMBPdfToJson started, daId:{}", daId);
        String json = null;

        try {
            CMB cmb = parseCMBPdf(filePath);
            json = JsonUtils.convertObjectToJson(cmb);
        } catch (Exception e) {
            log.error("OnError|{}||{}|{}|{}|{}", ErrorCode.FILE_PARSE_EXCEPTION.getCode(), daId, "", "", "parseCMBPdfToJson failed", e);
            return new ResponseData<String>(null, ErrorCode.FILE_PARSE_EXCEPTION.getCode(),
                    ErrorCode.FILE_PARSE_EXCEPTION.getMsg());
        }

        log.info("parseCMBPdfToJson completed, daId:{}", daId);
        return new ResponseData<String>(json, ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
    }

    public CMB parseCMBPdf(String filePath) {
        CMB cmb = parseCMBHeader(filePath);
        List<CMBTran> cmbTrans = parseCMBTrans(filePath);
        if (CollectionUtils.isEmpty(cmbTrans)) {
            cmbTrans = parseCMBTransByTabula(filePath);
        }
        cmb.setCmbTrans(cmbTrans);
        log.info("cmb statement = " + cmb);
        return cmb;
    }

    private CMB parseCMBHeader(String filePath) {
        CMB cmb = new CMB();
        String pdfHeaderText = parsePdfHeaderText(filePath);
        pdfHeaderText = pdfHeaderText.substring(0, pdfHeaderText.indexOf("Date Verification Code"));

        String transDetailPeriod = pdfHeaderText
                .substring(pdfHeaderText.indexOf("China Merchants Bank") + 20, pdfHeaderText.indexOf("户")).trim();
        String name = pdfHeaderText.substring(pdfHeaderText.indexOf("名：") + 2, pdfHeaderText.indexOf("账号：")).trim();
        String accountNo = pdfHeaderText
                .substring(pdfHeaderText.indexOf("账号：") + 3, pdfHeaderText.indexOf("Name Account")).trim();
        String accountType = pdfHeaderText
                .substring(pdfHeaderText.indexOf("账户类型：") + 5, pdfHeaderText.indexOf("开 户 行：")).trim();
        String subBranch = pdfHeaderText
                .substring(pdfHeaderText.indexOf("开 户 行：") + 6, pdfHeaderText.indexOf("Account Type")).trim();
        String date = pdfHeaderText.substring(pdfHeaderText.indexOf("申请时间：") + 5, pdfHeaderText.indexOf("验 证 码："))
                .trim();
        String verificationCode = pdfHeaderText.substring(pdfHeaderText.indexOf("验 证 码：") + 6).trim();
        cmb.setTransDetailPeriod(transDetailPeriod);
        cmb.setName(name);
        cmb.setAccountNo(accountNo);
        cmb.setAccountType(accountType);
        cmb.setSubBranch(subBranch);
        cmb.setDate(date);
        cmb.setVerificationCode(verificationCode);

        return cmb;
    }

    private List<CMBTran> parseCMBTrans(String filePath) {
        List<CMBTran> cmbTrans = new ArrayList<>();

        String transText = parseTransToText(filePath);
        if (Strings.isNullOrEmpty(transText)) {
            return cmbTrans;
        }

        boolean hasCounterPartyCol = hasCounterPartyColumn(filePath);

        List<List<String>> tranFieldsList = parseTransTextToTranFieldsList(transText);

        for (List<String> strings : tranFieldsList) {
            // 去除表头
            if (StringUtils.containsAny(strings.get(0), "Date")) {
                continue;
            }
            // 正常情况下有6个col
            if (strings.size() == 6) {
                boolean isEndOfNewTran = !Strings.isNullOrEmpty(strings.get(0));
                if (isEndOfNewTran) {
                    if (isAmountAndBalanceStickTogether(strings.get(2))) {
                        CMBTran cmbTran = new CMBTran();
                        cmbTran.setDate(strings.get(0));
                        cmbTran.setCurrency(strings.get(1));
                        splitTransactionAmountAndBalance(cmbTran, strings.get(2));
                        if (StringUtils.isBlank(strings.get(4))) {
                            cmbTran.setTransactionType(strings.get(3));
                        } else {
                            cmbTran.setTransactionType(strings.get(4));
                        }
                        cmbTran.setCounterParty(strings.get(5));
                        cmbTrans.add(cmbTran);
                    } else {
                        CMBTran cmbTran = new CMBTran();
                        cmbTran.setDate(strings.get(0));
                        cmbTran.setCurrency(strings.get(1));
                        cmbTran.setTransactionAmount(strings.get(2));
                        cmbTran.setBalance(strings.get(3));
                        cmbTran.setTransactionType(strings.get(4));
                        cmbTran.setCounterParty(strings.get(5));
                        cmbTrans.add(cmbTran);
                    }
                }
            }
            // 两种情况下，会出现size=5
            else if (strings.size() == 5) {
                // 1、没有"对手信息"这一个col
                if (!hasCounterPartyCol) {
                    if (StringUtils.isNotBlank(strings.get(0))) {
                        CMBTran cmbTran = new CMBTran();
                        cmbTran.setDate(strings.get(0));
                        cmbTran.setCurrency(strings.get(1));
                        cmbTran.setTransactionAmount(strings.get(2));
                        cmbTran.setBalance(strings.get(3));
                        cmbTran.setTransactionType(strings.get(4));
                        cmbTrans.add(cmbTran);
                    }
                }
                // 2、"交易金额" 和 "联机余额" 两个col粘到一起了
                else {
                    if (StringUtils.isNotBlank(strings.get(0)) && isAmountAndBalanceStickTogether(strings.get(2))) {
                        CMBTran cmbTran = new CMBTran();
                        cmbTran.setDate(strings.get(0));
                        cmbTran.setCurrency(strings.get(1));
                        splitTransactionAmountAndBalance(cmbTran, strings.get(2));
                        cmbTran.setTransactionType(strings.get(3));
                        cmbTran.setCounterParty(strings.get(4));
                        cmbTrans.add(cmbTran);
                    }
                }
            }
        }

        if (hasCounterPartyCol) {
            try {
                cmbTrans = parseConterparty(filePath, cmbTrans);
            } catch (Exception e) {
                log.warn("parseConterparty failed", e);
            }
        }

        return cmbTrans;
    }

    private boolean isAmountAndBalanceStickTogether(String text) {
        // -1,700.001,583.07
        return text.trim().matches("-?(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))");
    }

    // -1,700.001,583.07
    private void splitTransactionAmountAndBalance(CMBTran cmbTran, String str) {
        Pattern pattern = Pattern.compile("-?([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2})");
        Matcher matcher = pattern.matcher(str);
        if (matcher.find()) {
            cmbTran.setTransactionAmount(matcher.group());
        }

        if (matcher.find()) {
            cmbTran.setBalance(matcher.group());
        }
    }

    private String parseTransToText(String filePath) {
        PDFTableExtractor extractor = (new PDFTableExtractor()).setSource(filePath);
        int pdfPageNumber = getPdfPageNumber(filePath);
        // 去掉第一页的Header，
        int[] skipFirstPageHeaderLinesIndexes = new int[CMB_PDF_HEADER_LINE_NUMBER];
        for (int i = 0; i < CMB_PDF_HEADER_LINE_NUMBER; i++) {
            skipFirstPageHeaderLinesIndexes[i] = i;
        }
        extractor.exceptLine(0, skipFirstPageHeaderLinesIndexes);

        // 处理从第二页到最后一页的header
        for (int i = 1; i < pdfPageNumber; i++) {
            int[] skipLinesInNoneFirstPage = {0, 1};
            extractor.exceptLine(i, skipLinesInNoneFirstPage);
        }

        // 去掉最后一页的Footer,两种情况
        int lineNumberInLastPdf = getLineNumberInLastPage(filePath, pdfPageNumber);
        // 1.footer文本行完整展现在最后一页PDF,则直接排除最后一页的footer文本行
        if (lineNumberInLastPdf >= CMB_PDF_FOOTER_LINE_NUMBER) {
            int[] skipLastPageFooterLinesIndexes = new int[CMB_PDF_FOOTER_LINE_NUMBER];
            for (int j = 0; j < CMB_PDF_FOOTER_LINE_NUMBER; j++) {
                skipLastPageFooterLinesIndexes[j] = -(j + 1);
            }
            extractor.exceptLine(pdfPageNumber - 1, skipLastPageFooterLinesIndexes);
        } else {
            // 2.footer文本行拆分在倒数第一页和倒数第二页，则直接排除最后一页和倒数第二页的WECHAT_FOOTER_LINE_NO-lineNumberInLastPdf
            extractor.exceptPage(pdfPageNumber - 1);

            int footerLinesNumberInlastSecondPage = CMB_PDF_FOOTER_LINE_NUMBER - lineNumberInLastPdf;
            int[] skipLastSecondPageFooterLinesIndexes = new int[footerLinesNumberInlastSecondPage];
            for (int k = 0; k < footerLinesNumberInlastSecondPage; k++) {
                skipLastSecondPageFooterLinesIndexes[k] = -(k + 1);
            }
            extractor.exceptLine(pdfPageNumber - 2, skipLastSecondPageFooterLinesIndexes);
        }

        return extractPdfToText(extractor);
    }

    private boolean hasCounterPartyColumn(String filePath) {
        String pdfHeaderText = parsePdfHeaderText(filePath);
        if (pdfHeaderText.contains("对手信息") && pdfHeaderText.contains("Counter Party")) {
            return true;
        }
        return false;
    }


    public List<CMBTran> parseConterparty(String filePath, List<CMBTran> cmbTrans) {
        String pdfText = getPdfTextByStripper(filePath);
        pdfText = pdfText.replace(System.getProperty("line.separator", "\n"), " ");

        // 此处一行的格式2020-09-21 人民币 0.00 1.77 账户结息 应付利息-应付个人活期存款利息(自动计提)（新)
        // 973157320611009110
        Pattern pattern1 = Pattern
                .compile("\\d{4}-\\d{2}-\\d{2}\\s\\S{1,10}\\s-?(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{1,2}))(\\s)?(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{1,2}))\\s\\S{1,20}\\s");//NOSONAR

        Matcher matcher1 = pattern1.matcher(pdfText);

        // 每行交易记录的第一个字所在的index
        int tranIndex = 0;
        Map<Integer, Integer> tranTextStartIndexMap = new HashMap<>();

        while (matcher1.find()) {
//			log.info(
//			"Match \"" + matcher1.group() + "\" at positions " + matcher1.start() + "-" + (matcher1.end() - 1));
            tranTextStartIndexMap.put(tranIndex, matcher1.start());
            tranIndex++;
        }

        // 找出每行交易记录的文本
        List<String> tranTextList = new ArrayList<>();
        for (int i = 1; i < tranTextStartIndexMap.size(); i++) {
            String tranText = pdfText.substring(tranTextStartIndexMap.get(i - 1), tranTextStartIndexMap.get(i));
            if (tranText.contains("记账日期")) {
                tranText = tranText.substring(0, tranText.indexOf("/") - 2).trim();
            }
            if (tranText.contains("—————")) {
                tranText = tranText.substring(0, tranText.indexOf("—————")).trim();
            }
            tranTextList.add(tranText);
        }

        String lastTranText = pdfText.substring(tranTextStartIndexMap.get(tranTextStartIndexMap.size() - 1));
        if (lastTranText.contains("合并统计")) {
            lastTranText = lastTranText.substring(0, lastTranText.indexOf("合并统计")).trim();
        }
        if (lastTranText.contains("—————")) {
            lastTranText = lastTranText.substring(0, lastTranText.indexOf("—————")).trim();
        }
        tranTextList.add(lastTranText);

        // 找出每行交易里的对手信息的值
        // 此处一行除去对手信息的格式2020-09-21 人民币 0.00 1.77 账户结息
        Pattern pattern2 = Pattern
                .compile("\\d{4}-\\d{2}-\\d{2}\\s\\S{1,10}\\s-?(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{1,2}))(\\s)?(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{1,2}))\\s\\S{1,20}");//NOSONAR
        for (int i = 0; i < cmbTrans.size(); i++) {
            Matcher matcher2 = pattern2.matcher(tranTextList.get(i));
            while (matcher2.find()) {
                String counterParty = tranTextList.get(i).substring(matcher2.end()).trim();
                cmbTrans.get(i).setCounterParty(counterParty.replace(" ", ""));
            }
        }

        return cmbTrans;
    }

    private List<List<String>> parseCMBTransToRowList(String filePath) {
        //页面所有table的记录，每一个元素代表下面一条记录cellList
        List<List<String>> rowList = new ArrayList<>();

        // 1. 读取文件
        File pdf = new File(filePath);

        // 2. pdfbox读取PDDocument
        try (PDDocument pdfDocument = PDDocument.load(pdf)) {

            // 3. tabula新建ObjectExtractor和NurminenDetectionAlgorithm，同时准备接收表格Rectangle的结构
            ObjectExtractor objectExtractor = new ObjectExtractor(pdfDocument);
            NurminenDetectionAlgorithm detectionAlgorithm = new NurminenDetectionAlgorithm();
            Map<Integer, List<Rectangle>> detectedTables = new HashMap<>();

            // 4. 获取每页的PageIterator
            PageIterator pages = objectExtractor.extract();

            // 5. 解析每页的Rectangle(table的位置)
            while (pages.hasNext()) {
                Page page = pages.next();
                List<Rectangle> tablesOnPage = detectionAlgorithm.detect(page);
                if (tablesOnPage.size() > 0) {
                    detectedTables.put(page.getPageNumber(), tablesOnPage);
                }
            }

            // 6.通过table位置获取表格具体内容
            BasicExtractionAlgorithm bea = new BasicExtractionAlgorithm();

            // 如果单页pdf中有多个表格，则解析出来的List<Rectangle>会有多个对象
            for (Map.Entry<Integer, List<Rectangle>> entry : detectedTables.entrySet()) {
                Page page = objectExtractor.extract(entry.getKey());
                // 默认每页只有一个表格，因此获取第0个rectangle/
                Rectangle rectangle = null; //NOSONAR
                List<Rectangle> rectangleList = entry.getValue();
                for (Rectangle r : rectangleList) {
                    double rectangleHeight = r.getHeight();
                    if (Double.compare(rectangleHeight, 0) > 0) {
                        rectangle = r;
                        break;
                    }
                }
                if (rectangle == null) {
                    throw new RuntimeException("rectangle is null.");
                }
                rectangle.setBottom(rectangle.getBottom() + 900);
                rectangle.setRight(rectangle.getRight() + 300);
                Page area = page.getArea(rectangle);
                List<Table> tableList = null;
                try {
                    tableList = bea.extract(area);
                } catch (Exception e) {
                    log.info("rectangle extract table fail.");
                    continue;
                }
                for (Table table : tableList) {
                    for (int i = 0; i < table.getRowCount(); i++) {
                        // 过滤掉表头
                        if (StringUtils.containsAny(table.getCell(i, 0).getText(false), "记账日期", "Date")
                                || StringUtils.containsAny(table.getCell(i, 2).getText(false),
                                "Amount")
                                || StringUtils.containsAny(table.getCell(i, 1).getText(false),
                                "Amount", "Transaction")) {
                            continue;
                        }
                        List<String> cellList = new ArrayList<>();//一条记录，每个单元格占一个元素
                        for (int j = 0; j < table.getColCount(); j++) {
                            cellList.add(table.getCell(i, j).getText(false));
                        }
                        rowList.add(cellList);
                    }
                }

            }
            return rowList;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private List<CMBTran> parseCMBTransByTabula(String filePath) {
        List<CMBTran> cmbTrans = new ArrayList<>();
        List<List<String>> rowList = parseCMBTransToRowList(filePath);
        for (int i = 0; i < rowList.size(); i++) {
            List<String> cellList = rowList.get(i);
            if (cellList.get(0).matches("\\d{4}-\\d{2}-\\d{2}")) {
                if (cellList.size() == 6) {
                    CMBTran cmbTran = new CMBTran();
                    cmbTran.setDate(cellList.get(0));
                    cmbTran.setCurrency(cellList.get(1));
                    // 交易金额联机余额连在一起
                    if (StringUtils.isBlank(cellList.get(3)) && cellList.get(2).matches("-?(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))\\s+(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))")) {
                        splitTransactionAmountAndBalance(cmbTran, cellList.get(2));
                    } else {
                        cmbTran.setTransactionAmount(cellList.get(2));
                        cmbTran.setBalance(cellList.get(3));
                    }
                    cmbTran.setTransactionType(cellList.get(4));
                    // 对手信息跨行
                    if (i > 0 && i < rowList.size() - 1 && !cellList.get(5).matches(".+[0-9]{6}")) {
                        List<String> preCell = rowList.get(i - 1);
                        List<String> nextCell = rowList.get(i + 1);
                        String conunterParty = cellList.get(5);
                        if (StringUtils.isBlank(preCell.get(0)) && StringUtils.isNotBlank(preCell.get(5)) && !preCell.get(5).matches("[0-9]{1,3}/[0-9]{1,3}")) {
                            conunterParty = StringUtils.join(preCell.get(5), conunterParty);
                        }
                        if (StringUtils.isBlank(nextCell.get(0)) && StringUtils.isNotBlank(nextCell.get(5)) && !nextCell.get(5).matches("[0-9]{1,3}/[0-9]{1,3}")) {
                            conunterParty = StringUtils.join(conunterParty, nextCell.get(5));
                        }
                        cmbTran.setCounterParty(conunterParty);
                    } else {
                        cmbTran.setCounterParty(cellList.get(5));
                    }
                    cmbTrans.add(cmbTran);
                }
                // 记账日期和货币连在一起
            } else if (cellList.get(0).matches("\\d{4}-\\d{2}-\\d{2}\\s*\\S+")) {
                CMBTran cmbTran = new CMBTran();
                Pattern pattern = Pattern.compile("(\\d{4}-\\d{2}-\\d{2})\\s*(\\S+)");
                Matcher matcher = pattern.matcher(cellList.get(0));
                while (matcher.find()) {
                    cmbTran.setDate(matcher.group(1));
                    cmbTran.setCurrency(matcher.group(2));
                }
                // 交易金额联机余额连在一起
                if (StringUtils.isBlank(cellList.get(2)) && cellList.get(1).matches("-?(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))\\s+(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))")) {
                    splitTransactionAmountAndBalance(cmbTran, cellList.get(1));
                } else {
                    cmbTran.setTransactionAmount(cellList.get(1));
                    cmbTran.setBalance(cellList.get(2));
                }
                cmbTran.setTransactionType(cellList.get(3));

                // 对手信息跨行
                if (i > 0 && i < rowList.size() - 1 && !cellList.get(4).matches(".+[0-9]{6}")) {
                    List<String> preCell = rowList.get(i - 1);
                    List<String> nextCell = rowList.get(i + 1);
                    String conunterParty = cellList.get(4);
                    if (StringUtils.isBlank(preCell.get(0)) && StringUtils.isNotBlank(preCell.get(4)) && !preCell.get(4).matches("[0-9]{1,3}/[0-9]{1,3}")) {
                        conunterParty = StringUtils.join(preCell.get(4), conunterParty);
                    }
                    if (StringUtils.isBlank(nextCell.get(0)) && StringUtils.isNotBlank(nextCell.get(4)) && !nextCell.get(4).matches("[0-9]{1,3}/[0-9]{1,3}")) {
                        conunterParty = StringUtils.join(conunterParty, nextCell.get(4));
                    }
                    cmbTran.setCounterParty(conunterParty);
                } else {
                    cmbTran.setCounterParty(cellList.get(4));
                }
                cmbTrans.add(cmbTran);

                // XXXX有限公司2022-04-26 CNY
            } else if (cellList.get(0).matches("\\S+\\s*\\d{4}-\\d{2}-\\d{2}\\s*\\S+")) {
                CMBTran cmbTran = new CMBTran();
                Pattern pattern = Pattern.compile("(\\S+)\\s*(\\d{4}-\\d{2}-\\d{2})\\s*(\\S+)");
                Matcher matcher = pattern.matcher(cellList.get(0));
                String conunterParty = "";
                while (matcher.find()) {
                    conunterParty = matcher.group(1);
                    cmbTran.setDate(matcher.group(2));
                    cmbTran.setCurrency(matcher.group(3));
                }
                // 交易金额联机余额连在一起
                if (StringUtils.isBlank(cellList.get(2)) && cellList.get(1).matches("-?(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))\\s+(([0-9]{1,3}(,[0-9]{3})*)(\\.[0-9]{2}))")) {
                    splitTransactionAmountAndBalance(cmbTran, cellList.get(1));
                } else {
                    cmbTran.setTransactionAmount(cellList.get(1));
                    cmbTran.setBalance(cellList.get(2));
                }
                cmbTran.setTransactionType(cellList.get(3));
                // 对手信息跨行
                if (i > 0 && i < rowList.size() - 1 && !cellList.get(4).matches(".+[0-9]{6}")) {
                    conunterParty = StringUtils.join(conunterParty, cellList.get(4));
                    List<String> nextCell = rowList.get(i + 1);
                    if (StringUtils.isBlank(nextCell.get(0)) && StringUtils.isNotBlank(nextCell.get(4)) && !nextCell.get(4).matches("[0-9]{1,3}/[0-9]{1,3}")) {
                        conunterParty = StringUtils.join(conunterParty, nextCell.get(4));
                    }
                    cmbTran.setCounterParty(conunterParty);
                } else {
                    cmbTran.setCounterParty(cellList.get(4));
                }
                cmbTrans.add(cmbTran);
            }

        }
        return cmbTrans;
    }


    public static void main(String[] args) {
        CMBPdfParser cmbPdfParser = new CMBPdfParser();
        CMB cmb;
        String json;
        cmb = cmbPdfParser.parseCMBPdf("D:\\data\\files\\CMB\\zd20kldt1765676385071304704_c649e3fd773c7ae6fec82efe49ec7647_beehive-cmb_jyls-0.pdf");
        json = JsonUtils.convertObjectToJson(cmb);
        System.out.println(json);

//        cmb = cmbPdfParser.parseCMBPdf("D:\\data\\files\\CMB\\招商银行（含对手信息和完整卡号）.pdf");
//        json = JsonUtils.convertObjectToJson(cmb);
//        System.out.println(json);

//        cmb = cmbPdfParser.parseCMBPdf("D:\\data\\files\\CMB\\zd4g3dtt1586590138023227392_3fe03eb02cb67e71bb69ec298cde1ef1_beehive-cmb_jyls-0.pdf");
//        json = JsonUtils.convertObjectToJson(cmb);
//        System.out.println(json);

//        cmb = cmbPdfParser.parseCMBPdf("D:\\data\\files\\CMB\\zd2gpjd61565262407289520128_ef581bdb8c7fc03d95d9e7a29f164812_beehive-cmb_jyls-0.pdf");
//        json = JsonUtils.convertObjectToJson(cmb);
//        System.out.println(json);

//        cmb = cmbPdfParser.parseCMBPdf("D:\\data\\files\\CMB\\zdbae1qp1693880185087627264_19878bf3c2c920102aeb81d0f36ae96b_beehive-cmb_jyls-0.pdf");
//        json = JsonUtils.convertObjectToJson(cmb);
//        System.out.println(json);

    }

}
